<template>
  <view class="page-chart">
    <scroll-view class="box" scroll-y :scroll-top="scrollTop">
      <view class="container">
        <view class="tips">
          <view class="tips1">
            <view class="left">
              <image class="img" src="http://www.xinchengai.top:443/logo.png" mode="aspectFit" />
            </view>
            <view class="right">
              <view class="name">心程AI</view>
              <view class="text">内测功能内容由AI生成，仅供参考</view>
            </view>
          </view>
          <view class="tips2">
            <view class="left">
              <image class="img" src="http://www.xinchengai.top:443/logo.png" mode="aspectFit" />
            </view>
            <view class="right">
              <view class="text"> <van-icon name="info" /> AI生成内容仅供参考，详见《AI功能使用须知》 </view>
            </view>
          </view>
          <view class="tips3" v-if="!isReady"> 你好!欢迎使用校园霸凌自我检测工具。我们会通过一系列问题帮助你识别是否经历过校园霸凌。你准备好后我们就可以开始了。 </view>
          <view class="tips4" v-if="!isReady">
            <button class="col-l">了解更多</button>
            <button class="col-l" @click="startChart">准备好了</button>
          </view>
          <view class="tips5" v-if="!isReady">
            <view class="m-item" v-for="item in imageLists" :key="`${item.id}`">
              <image :class="{ active: choose === item.id }" :src="item.image" mode="aspectFit" @click="choose = item.id" />
              <text>{{ item.text }}</text>
            </view>
          </view>
        </view>
        <template v-if="isReady">
          <MessageItem v-for="(item, index) in chartLists" :key="index" :content="item.content" :type="item.role" @click="play(item)" />
          <MessageItem :content="loadingText" type="assistant" v-if="loading" />
        </template>
      </view>
    </scroll-view>
    <view
      class="input-box"
      :style="{
        paddingBottom: `${bottom}px`,
      }"
      v-if="isReady"
    >
      <input v-model="inputText" class="input" type="text" placeholder="点击输入" confirm-type="send" @confirm="confirm" />
      <button class="ui-btn" type="primary" size="mini" @touchstart="start" @touchend="end"></button>
    </view>
  </view>
</template>
<script setup>
import { ref, toRaw, onUnmounted } from "vue";
import MessageItem from "@/components/message.vue";
import { getConversationID, chatContact, prefish } from "@/api";
import { onHide, onShow } from "@dcloudio/uni-app";

const plugin = requirePlugin("WechatSI");
let manager = plugin.getRecordRecognitionManager();
let player = uni.createInnerAudioContext();

const conversationID = ref();

const { safeAreaInsets } = uni.getSystemInfoSync();

const bottom = ref(safeAreaInsets.bottom);
const loading = ref(false);
const loadingText = ref("");
const isReady = ref(false);

const choose = ref(NaN);
const scrollTop = ref(0);

const inputText = ref("");
const sessionId = ref("");

const imageLists = ref([
  {
    image: "http://www.xinchengai.top:443/fl1.png",
    id: 1,
    text: "言语霸凌",
  },
  {
    image: "http://www.xinchengai.top:443/fl2.png",
    id: 2,
    text: "社交排斥",
  },
  {
    image: "http://www.xinchengai.top:443/fl3.png",
    id: 3,
    text: "网络霸凌",
  },
  {
    image: "http://www.xinchengai.top:443/fl4.png",
    id: 4,
    text: "身体霸凌",
  },
]);

const chartLists = ref([
  {
    role: "assistant",
    content: "你好!欢迎使用校园霸凌自我检测工具。我们会通过一系列问题帮助你识别是否经历过校园霸凌。你准备好后我们就可以开始了。",
  },
]);

const handleScollTop = () => {
  return new Promise((resolve) => {
    const query = wx.createSelectorQuery();
    query.select(".box").boundingClientRect();
    query.select(".container").boundingClientRect();
    query.exec((res) => {
      const scrollViewHeight = res[0].height;
      const scrollContentHeight = res[1].height;
      if (scrollContentHeight > scrollViewHeight) {
        const top = scrollContentHeight - scrollViewHeight;
        scrollTop.value = top + 300;
        resolve();
      } else {
        resolve();
      }
    });
  });
};

manager.onStop = function (res) {
  if (res.result === "") {
    uni.showModal({
      title: "提示",
      content: "没有听清，请再说一次~",
      showCancel: false,
    });
    return;
  }
  inputText.value = res.result;
};

manager.onError = function (res) {
  console.error("error msg", res);
  const tips = {
    "-30003": "说话时间间隔太短，无法识别语音",
    "-30004": "没有听清，请再说一次~",
    "-30011": "上个录音正在识别中，请稍后尝试",
  };
  const retcode = res?.retcode.toString();
  retcode &&
    uni.showToast({
      title: tips[`${retcode}`],
      icon: "none",
      duration: 2000,
    });
};

const start = () => {
  manager.start({
    duration: 30 * 1000,
    lang: "zh_CN",
  });
};

const end = () => {
  manager.stop();
};

const startChart = () => {
  if (!choose.value) {
    return uni.showToast({
      title: "请选择一个分类",
      icon: "none",
    });
  }
  getConversationID().then((res) => {
    conversationID.value = res.conversationID;
    isReady.value = true;
    const item = imageLists.value.find((item) => item.id === choose.value);
    chartLists.value.push({
      role: "user",
      content: item.text,
      time: +new Date(),
    });
    beginMessage();
  });
};

const handleRequestResolve = (result) => {
  const contentCharArr = result.trim().split("");
  this.setData({
    thinking: false,
    [newMessageList]: {
      id: timestamp,
      role: "assistant",
      finished: false,
    },
  });
  currentContent = "";
  this.showText(0, content_key, finished_key, contentCharArr);
};

// 播放语音
const play = (item) => {
  if (item.role === "assistant" && player) {
    player.src = item.sessionId;
    player.play(); // 播放
  }
};

// 开始对话
const beginMessage = () => {
  loading.value = true;
  loadingText.value = "思考中...";
  const userInfo = uni.getStorageSync("userInfo") || {};

  const data = JSON.parse(JSON.stringify(chartLists.value));
  data.shift();
  const requestTask = uni.request({
    url: "https://www.xinchengai.top:8080/chatContact",
    enableChunked: true,
    method: "post",
    timeout: 30 * 1000,
    data: {
      conversationID: conversationID.value,
      membershipStatus: "",
      messages: data,
    },
    header: {
      openID: userInfo.openid,
    },
    success: () => {
      loading.value = false;
      if (loadingText.value) {
        chartLists.value.push({
          role: "assistant",
          content: loadingText.value,
          sessionId: sessionId.value,
          time: +new Date(),
        });
        sessionId.value = "";
        loadingText.value = "";
      }
      console.log("chartLists", chartLists.value);
      if (chartLists.value.length > 10) {
        submit();
      }
    },
    fail: () => {
      loading.value = false;
    },
  });

  requestTask.onHeadersReceived(function (res) {
    loadingText.value = "";
  });

  requestTask.onChunkReceived(async (response) => {
    const uint8Array = new Uint8Array(response.data);
    let text = String.fromCharCode.apply(null, uint8Array);
    text = decodeURIComponent(escape(text));
    const [reallyText, sessionUrl] = text.split("<EOF>");
    loadingText.value += reallyText;
    await handleScollTop();
    // 这里存的是语音的地址
    if (sessionUrl) {
      sessionId.value = sessionUrl;
    }
  });
};

// 获取答案
const confirm = (e) => {
  if (inputText.value) {
    chartLists.value.push({
      role: "user",
      content: inputText.value,
      time: +new Date(),
    });
    inputText.value = "";
    handleScollTop();
    beginMessage();
  }
};

// 最后提交数据
const submit = () => {
  const data = JSON.parse(JSON.stringify(chartLists.value));
  data.shift();
  uni.showModal({
    title: "提示",
    content: "是否需要脱敏（保护学生的部分隐私）?",
    cancelText: "否",
    confirmText: "是",
    success: function (res) {
      let isAnonymou = false;
      if (res.confirm) {
        isAnonymou = true;
      }
      prefish({
        membershipStatus: "",
        isAnonymou,
        messages: data,
      }).then((res) => {
        uni.redirectTo({
          url: `/pages/result/index?id=${res.insertidID}`,
        });
      });
    },
  });
};

onShow(() => {
  if (!player) {
    player = uni.createInnerAudioContext();
  }
});

onUnmounted(() => {
  player.destroy();
});
</script>

<style lang="scss" scoped>
.page-chart {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #ad9f89;
  .box {
    flex: 1 0 auto;
    height: 50%;
  }
  .container {
    box-sizing: border-box;
    padding: 20rpx;
    .tips {
      .tips1 {
        display: flex;
        align-items: center;
        margin-bottom: 40rpx;
        .left {
          width: 80rpx;
          height: 80rpx;
          .img {
            width: 100%;
            height: 100%;
          }
        }
        .right {
          color: #fff;
          .name {
            font-size: 28rpx;
          }
          .text {
            color: rgba($color: #fff, $alpha: 0.5);
            font-size: 24rpx;
          }
        }
      }
      .tips2 {
        display: flex;
        flex-direction: column;
        align-items: center;
        margin-bottom: 40rpx;
        .left {
          width: 240rpx;
          height: 240rpx;
          .img {
            width: 100%;
            height: 100%;
          }
        }
        .right {
          max-width: 80%;
          font-size: 24rpx;
          color: #fff;
        }
      }
      .tips3 {
        color: #fff;
        background: rgba($color: #fff, $alpha: 0.2);
        padding: 20rpx;
        border-radius: 20rpx;
        color: #fff;
        font-size: 26rpx;
        box-sizing: border-box;
        margin: 0 40rpx 40rpx 40rpx;
      }
      .tips4 {
        display: flex;
        margin-bottom: 40rpx;
        .col-l,
        .col-r {
          width: calc(50% - 80rpx);
          flex: 1 0 auto;
          font-size: 24rpx;
          background: none;
          margin: 0 40rpx;
          color: #fff;
          border: 2rpx solid #fff;
          box-sizing: border-box;
          &::after {
            border-color: #fff;
            display: none;
          }
        }
      }
      .tips5 {
        display: flex;
        flex-wrap: wrap;
        gap: 20rpx;
        .m-item {
          text-align: center;
          font-size: 28rpx;
          color: #fff;
        }
        image {
          width: calc((100vw - 60rpx) / 2);
          height: calc((100vw - 60rpx) / 2);
          box-sizing: border-box;
          display: block;
          border: 4rpx solid transparent;
          margin-bottom: 20rpx;
          &.active {
            border-color: black;
          }
        }
      }
    }
  }
  .input-box {
    flex: 0 0 auto;
    height: 100px;
    padding: 0 20rpx;
    box-sizing: border-box;
    display: flex;

    .input {
      flex: 1 0 auto;
      height: 80rpx;
      border: 2rpx solid rgba($color: #fff, $alpha: 0.5);
      border-radius: 10rpx;
      padding: 0 20rpx;
      box-sizing: border-box;
      font-size: 28rpx;
      color: #fff;
    }
    .ui-btn {
      width: 80rpx;
      height: 80rpx;
      background: url("http://www.xinchengai.top:443/icon-sy.png") no-repeat center center;
      background-size: 100% 100%;
      margin-left: 20rpx;
      border: none;
      padding: 0;
      &::after {
        border: none;
      }
    }
  }
}
</style>
